﻿using DataModels.Dto;
using DataModels.Dto.Community;
using DataModels.Entities.Base;
using DataModels.Entities.Community;
using DataModels.Enums.Community;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using QRCoder;
using SqlSugar;
using System.Drawing;
using System.Drawing.Imaging;
using System.Security.Policy;
using System.Text.Json;
using System.Xml.Linq;
using Utils;
using static Azure.Core.HttpHeader;
using static DataModels.Enums.GeneralEnum;
using static System.Net.Mime.MediaTypeNames;

namespace Services.Community
{
    /// <summary>
    /// 服务评价API
    /// </summary>
    public class ServiceEvaluationService(SqlSugarClient db) : BaseService(db)
    {
        /// <summary>
        /// 提交服务评价 modify by tianjh20250803
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public ResponseModel SubmitServiceEvaluation(SubmitServiceEvaluationInfo info)
        {
            if (info == null)
                return Error("缺失参数");

            try
            {
                ServiceEvaluation se = db.Queryable<ServiceEvaluation>()
                    .Where(se => se.Status == DataModels.Enums.GeneralEnum.Status.Enable)
                    .Where(se => se.UUID == info.ServiceEvaluationUUID)
                    .Where(se => se.ProjectUUID == info.ProjectUUID)
                    .First();
                if (se == null)
                    return Error("问卷不存在");

                bool sehexist = db.Queryable<ServiceEvaluationHistory>()
                    .Where(seh => seh.ServiceEvaluationUUID == se.UUID)
                    .Where(seh => seh.CreateUser == UserUUID)
                    .OrderBy(seh => seh.CreateTime, OrderByType.Desc)
                    .Any();
                if (sehexist)
                    return Success(new {UserUUID, Message= "您已提交过该问卷", IsSubmit = true });

                if (string.IsNullOrEmpty(se.Content))
                    return Error("问卷内容不存在");

                //解析原始问卷的内容
                ServiceEvaluationContent sec = JsonConvert.DeserializeObject<ServiceEvaluationContent>(se.Content);
                if (sec == null)
                    return Error("问卷内容格式错误");

                //解析本次提交的答案
                ServiceEvaluationResponse ser = JsonConvert.DeserializeObject<ServiceEvaluationResponse>(info.Content);
                if (ser == null)
                    return Error("问卷答案格式错误");

                if (sec.questions != null && sec.questions.Count != ser.responses.Count)
                    return Error("问卷答案与题目数量不一致");

                List<ServiceEvaluationResult> resultList = new List<ServiceEvaluationResult>();
                int index = 1;

                foreach (var item in sec.questions)
                {
                    if (item == null)
                        continue;

                    string type = item.type.ToLower();
                    string id = item.id;

                    ServiceEvaluationResult serEntity = new ServiceEvaluationResult();
                    serEntity.UUID = Guid.NewGuid().ToString().ToLower();
                    serEntity.ServiceEvaluationUUID = info.ServiceEvaluationUUID.ToString();
                    serEntity.CreateUser = UserUUID.ToString();
                    serEntity.CreateTime = DateTime.Now;
                    serEntity.No = index;

                    if (type == ServiceEvaluationControlType.single.ToString()) //单选题
                    {
                        serEntity.Type = EnumUtil.GetNumericValue(ServiceEvaluationControlType.single);
                        serEntity.TypeDesc = EnumUtil.GetDescription(ServiceEvaluationControlType.single);
                        serEntity.TypeName = type;
                        serEntity.Title = item.title;
                        serEntity.ResultValue = ser.responses[id].ToString();
                        serEntity.ResultText = item.options?.FirstOrDefault(option => option?.value == serEntity.ResultValue)?.text;
                    }
                    else if (type == ServiceEvaluationControlType.multiple.ToString()) //多选题
                    {
                        serEntity.Type = EnumUtil.GetNumericValue(ServiceEvaluationControlType.multiple);
                        serEntity.TypeDesc = EnumUtil.GetDescription(ServiceEvaluationControlType.multiple);
                        serEntity.TypeName = type;
                        serEntity.Title = item.title;
                        JArray jarry = ser.responses[id] as JArray;
                        string[] arr = jarry.ToObject<string[]>();
                        serEntity.ResultValue = string.Join(",", arr);
                        serEntity.ResultText = string.Join(", ",
                                 item.options?.Where(opt => opt != null && !string.IsNullOrEmpty(opt.value) && arr.Contains(opt.value))
                                 .Select(opt => opt.text)
                                 .Where(text => !string.IsNullOrEmpty(text)) ?? Enumerable.Empty<string>());
                    }
                    else if (type == ServiceEvaluationControlType.input.ToString()) //填空题
                    {
                        serEntity.Type = EnumUtil.GetNumericValue(ServiceEvaluationControlType.input);
                        serEntity.TypeDesc = EnumUtil.GetDescription(ServiceEvaluationControlType.input);
                        serEntity.TypeName = type;
                        serEntity.Title = item.title;
                        serEntity.ResultValue = ser.responses[id].ToString();
                        serEntity.ResultText = serEntity.ResultValue;
                    }
                    else if (type == ServiceEvaluationControlType.inputs.ToString()) //多项填空
                    {
                        serEntity.Type = EnumUtil.GetNumericValue(ServiceEvaluationControlType.inputs);
                        serEntity.TypeDesc = EnumUtil.GetDescription(ServiceEvaluationControlType.inputs);
                        serEntity.TypeName = type;
                        serEntity.Title = item.title;

                        JArray jarry = ser.responses[id] as JArray;
                        string[] arr = jarry.ToObject<string[]>();
                        serEntity.ResultValue = string.Join(",", arr);
                        serEntity.ResultText = serEntity.ResultValue;
                    }
                    else if (type == ServiceEvaluationControlType.text.ToString()) //多行文本
                    {
                        serEntity.Type = EnumUtil.GetNumericValue(ServiceEvaluationControlType.text);
                        serEntity.TypeDesc = EnumUtil.GetDescription(ServiceEvaluationControlType.text);
                        serEntity.TypeName = type;
                        serEntity.Title = item.title;
                        serEntity.ResultValue = ser.responses[id].ToString();
                        serEntity.ResultText = serEntity.ResultValue;
                    }
                    else if (type == ServiceEvaluationControlType.rating.ToString()) //评分题
                    {
                        serEntity.Type = EnumUtil.GetNumericValue(ServiceEvaluationControlType.rating);
                        serEntity.TypeDesc = EnumUtil.GetDescription(ServiceEvaluationControlType.rating);
                        serEntity.TypeName = type;
                        serEntity.Title = item.title;
                        serEntity.ResultValue = ser.responses[id].ToString();
                        serEntity.ResultText = serEntity.ResultValue;
                    }
                    else if (type == "vote" && item.candidates != null && item.candidates.Count > 0) //候选人投票
                    {
                        serEntity.Type = EnumUtil.GetNumericValue(ServiceEvaluationControlType.CandidateVoting);
                        serEntity.TypeDesc = EnumUtil.GetDescription(ServiceEvaluationControlType.CandidateVoting);
                        serEntity.TypeName = type;
                        serEntity.Title = item.title;
                        JArray jarry = ser.responses[id] as JArray;
                        int[] arr = jarry.ToObject<int[]>();
                        serEntity.ResultValue = string.Join(",", arr);
                        serEntity.ResultText = string.Join(", ",
                                    arr.Where(index => index >= 0 && index < item.candidates.Count)
                                    .Select(index => item.candidates[index]?.name)
                                    .Where(name => !string.IsNullOrEmpty(name)));
                    }
                    else if (type == "vote" && item.options != null && item.options.Count > 0) //选项投票
                    {
                        serEntity.Type = EnumUtil.GetNumericValue(ServiceEvaluationControlType.OptionVoting);
                        serEntity.TypeDesc = EnumUtil.GetDescription(ServiceEvaluationControlType.OptionVoting);
                        serEntity.TypeName = type;
                        serEntity.Title = item.title;
                        JArray jarry = ser.responses[id] as JArray;
                        string[] arr = jarry.ToObject<string[]>();
                        serEntity.ResultValue = string.Join(",", arr);
                        serEntity.ResultText = string.Join(", ",
                                 item.options?.Where(opt => opt != null && !string.IsNullOrEmpty(opt.value) && arr.Contains(opt.value))
                                 .Select(opt => opt.text)
                                 .Where(text => !string.IsNullOrEmpty(text)) ?? Enumerable.Empty<string>());
                    }

                    resultList.Add(serEntity);
                    index++;
                }

                db.Ado.BeginTran(); //开启事物

                //插入历史表
                ServiceEvaluationHistory hisEntity = new()
                {
                    ServiceEvaluationUUID = info.ServiceEvaluationUUID,
                    Title = info.Title,
                    Content = info.Content,
                    CreateUser = UserUUID
                };
                db.Insertable(hisEntity).ExecuteCommand();

                //插入答题结果表      
                db.Insertable(resultList).ExecuteCommand();

                db.Ado.CommitTran(); //提交事物

                return Success();
            }
            catch (Exception ex)
            {
                db.Ado.RollbackTran(); //回滚事物

                return Error($"提交服务评价失败 {ex.Message}");
            }
        }
        
        /// <summary>
        /// 通过问卷UUID获取服务评价
        /// </summary>
        /// <param name="ProjectUUID"></param>
        /// <returns></returns>
        public ResponseModel GetLastServiceEvaluationByUUID(Guid UUID)
        {
            bool IsSubmit = db.Queryable<ServiceEvaluationResult>().Any(n => n.CreateUser == UserUUID.ToString() && n.ServiceEvaluationUUID == UUID.ToString());
            var se = db.Queryable<ServiceEvaluation>()
                .Where(se => se.Status == DataModels.Enums.GeneralEnum.Status.Enable)
                .Where(se => se.UUID == UUID)
                .OrderBy(se => se.CreateTime, OrderByType.Desc)
                .Select(se => new
                {
                    se.UUID,
                    se.Title,
                    se.Content,
                    se.CreateUser,
                    se.CreateTime,
                    IsSubmit
                })
                .First();
            if (se == null)
            {
                return Success();
            }
            var seh = db.Queryable<ServiceEvaluationHistory>()
            .Where(seh => seh.ServiceEvaluationUUID == se.UUID)
            .Where(seh => seh.CreateUser == UserUUID)
            .OrderBy(seh => seh.CreateTime, OrderByType.Desc)
            .Select(seh => new
            {
                se.UUID,
                seh.Title,
                seh.Content,
                se.CreateUser,
                se.CreateTime,
                IsSubmit
            })
            .First();

            return seh != null ? Success(seh) : Success(se);
        }

        /// <summary>
        /// 通过问卷activitiesNumber获取服务评价
        /// </summary>
        /// <param name="activitiesNumber"></param>
        /// <returns></returns>
        public ResponseModel GetServiceEvaluationByactivitiesNumber(int activitiesNumber)
        {
            var se = db.Queryable<ServiceEvaluation>()
                .Where(se => se.Status == DataModels.Enums.GeneralEnum.Status.Enable)
                .Where(se => se.activitiesNumber == activitiesNumber)
                .OrderBy(se => se.CreateTime, OrderByType.Desc)
                .Select(se => new ServiceEvaluation
                {
                    UUID = se.UUID,
                    Title = se.Title,
                    Content = se.Content,
                    CreateUser = se.CreateUser,
                    CreateTime = se.CreateTime,
                    IsSubmit = false
                })
                .First();
            if (se == null)
            {
                return Success();
            }
            bool IsSubmit = db.Queryable<ServiceEvaluationResult>().Any(n => n.CreateUser == UserUUID.ToString() && n.ServiceEvaluationUUID ==se.UUID.ToString());
            se.IsSubmit = IsSubmit;

            var seh = db.Queryable<ServiceEvaluationHistory>()
            .Where(seh => seh.ServiceEvaluationUUID == se.UUID)
            .Where(seh => seh.CreateUser == UserUUID)
            .OrderBy(seh => seh.CreateTime, OrderByType.Desc)
            .Select(seh => new
            {
                se.UUID,
                seh.Title,
                seh.Content,
                se.CreateUser,
                se.CreateTime,
                IsSubmit
            })
            .First();

            return seh != null ? Success(seh) : Success(se);
        }

        /// <summary>
        /// 获取最新一条服务评价
        /// </summary>
        /// <param name="ProjectUUID"></param>
        /// <returns></returns>
        public ResponseModel GetLastServiceEvaluation(Guid ProjectUUID)
        {
            var se = db.Queryable<ServiceEvaluation>()
                .Where(se => se.Status == DataModels.Enums.GeneralEnum.Status.Enable)
                .Where(se => se.ProjectUUID == ProjectUUID)
                .OrderBy(se => se.CreateTime, OrderByType.Desc)
                .Select(se => new
                {
                    se.UUID,
                    se.Title,
                    se.Content,
                    se.CreateUser,
                    se.CreateTime
                })
                .First();
            if (se == null)
            {
                return Success();
            }

            var seh = db.Queryable<ServiceEvaluationHistory>()
            .Where(seh => seh.ServiceEvaluationUUID == se.UUID)
            .Where(seh => seh.CreateUser == UserUUID)
            .OrderBy(seh => seh.CreateTime, OrderByType.Desc)
            .Select(seh => new
            {
                se.UUID,
                seh.Title,
                seh.Content,
                se.CreateUser,
                se.CreateTime
            })
            .First();

            return seh != null ? Success(seh) : Success(se);
        }
        /// <summary>
        /// 获取服务评价列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public ResponseModel GetServiceEvaluationList(ServiceEvaluationInfo info)
        {
            if (info == null)
                return Error("缺失参数");

            var total = 0;

            try
            {
                var list = db.Queryable<ServiceEvaluation, Projects, Customer>((se, p, c) => new object[]
                {
                    JoinType.Left,se.ProjectUUID == p.UUID,
                    JoinType.Left,se.CreateUser == c.UUID
                })
                .WhereIF(!string.IsNullOrEmpty(info.Title), se => se.Title.Contains(info.Title))
                .WhereIF(!string.IsNullOrEmpty(info.ProjectUUID), se => se.ProjectUUID.ToString().Contains(info.ProjectUUID))
                .WhereIF(info.Status.HasValue, se => se.Status == info.Status)
                .Select((se, p, c) => new
                {
                    se.UUID,
                    se.Title,
                    se.Content,
                    se.CreateTime,
                    CreateName = c.Name,
                    se.Status,
                    se.ProjectUUID,
                    ProjectName = p.ProjectName,
                    se.IsTop
                    
                })
                .OrderByDescending (se => se.IsTop)
                 .OrderByDescending(se => se.CreateTime)
                .ToPageList(info.PageNumber, info.PageSize, ref total);

                return PageSuccess(info.PageNumber, info.PageSize, total, list);
            }
            catch (Exception ex)
            {
                return Error($"获取服务评价列表失败 {ex.Message}");
            }
        }

        /// <summary>
        /// 获取投票数量 
        /// </summary>
        /// <param name="ServiceEvaluationUUID"></param>
        /// <param name="No">题目号</param>
        /// <param name="Type">7候选人投票 8选项投票</param>
        /// <param name="Values">选项列表</param>
        /// <returns></returns>
        public ResponseModel GetVotesNumber(string ServiceEvaluationUUID, int No, int Type, Guid CreateUser)
        {
            if (string.IsNullOrEmpty(ServiceEvaluationUUID))
                return Error("缺失参数");

            try 
            {     
                bool IsSubmit = db.Queryable<ServiceEvaluationResult>().Any(n => n.CreateUser == CreateUser.ToString() && n.ServiceEvaluationUUID.ToString() == ServiceEvaluationUUID);
                var list = db.Queryable<ServiceEvaluationResult>()
                    .Where(ser => ser.ServiceEvaluationUUID == ServiceEvaluationUUID)
                    .Where(ser => ser.No == No && ser.Type == Type) 
                    .GroupBy(ser=>ser.ResultText)
                    //.OrderBy(ser => ser.CreateTime)
                    .Select(g => new
                    {
                        ResultText = g.ResultText,
                        Count = SqlFunc.AggregateCount(g.ResultText)
                    })
                    .ToList(); 

                var result = new
                {
                    No = No, 
                    Total = list.Count,
                    IsSubmit,
                    ValueCounts = list
                };
           
                return Success(result);
            }
            catch  (Exception ex)
            {
                return Error($"获取服务评价列表失败 {ex.Message}");
            }
        }

        /// <summary>
        /// 生成二维码
        /// </summary>
        /// <param name="Url"></param>
        /// <param name="Size"></param>
        /// <returns></returns>
        public byte[] GenerateQRCode(string Url, int Size)
        {   
            using (var qrGenerator = new QRCodeGenerator())
            {
                // 创建二维码数据
                var qrCodeData = qrGenerator.CreateQrCode(
                    Url,
                    QRCodeGenerator.ECCLevel.Q // 纠错级别
                );

                // 计算模块大小（每个小方块的像素）
                // 二维码的实际尺寸 = 模块大小 × (二维码版本大小 + 4)
                // 这里确保最终尺寸接近用户指定的size
                int moduleSize = Math.Max(1, (int)Math.Floor((double)Size / (qrCodeData.ModuleMatrix.Count + 4)));

                // 使用PngByteQRCode生成PNG格式图片
                var qrCode = new PngByteQRCode(qrCodeData);

                // 生成字节数组，传入模块大小参数
                byte[] qrCodeImage = qrCode.GetGraphic(moduleSize);

                // 返回图片
                return qrCodeImage;
            }
        }


    }
}
